home *** CD-ROM | disk | FTP | other *** search
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <limits.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <time.h>
- #include "netconf.h"
- #include "internal.h"
- #include "../userconf/userconf.h"
- #include "../fstab/fstab.h"
- #include "netconf.m"
-
- static const char DATETIME_P[]="datetime";
- static const char UNIVERSAL[]="universal";
- static const char NETDATE[]="netdate";
-
- static NETCONF_HELP_FILE help_date ("datetime");
-
- PUBLIC DATETIME::DATETIME()
- {
- universal = linuxconf_getvalnum (DATETIME_P,UNIVERSAL,0);
- netdate.setfrom (linuxconf_getval (DATETIME_P,NETDATE));
- }
-
- PUBLIC void DATETIME::save()
- {
- linuxconf_replace (DATETIME_P,UNIVERSAL,universal);
- linuxconf_replace (DATETIME_P,NETDATE,netdate);
- linuxconf_save();
- }
-
- /*
- Extract recursivly a directory, getting all files.
- tbf will contain the path relative to a certain path (using
- skip_prefix to strip the beginning).
- */
- static void datetime_zonelst (
- int skip_prefix,
- SSTRINGS &tbf,
- const char *path)
- {
- /* #Specification: netconf / datetime / zoneinfo / options
- netconf finds the possible time zone available by listing
- the content of the directory /usr/lib/zoneinfo. It does it
- recursivly. It avoid symbolic links and executable file.
- The file "time.doc" is also removed explicitly since many
- slackware do contain it.
- */
- int start = tbf.getnb();
- dir_getlist (path,tbf);
- int end = tbf.getnb();
- for (int i=start; i<end; i++){
- char fpath[PATH_MAX];
- SSTRING *str = tbf.getitem(i);
- const char *pt = str->get();
- sprintf (fpath,"%s/%s",path,pt);
- struct stat st;
- char *replace = "";
- if (lstat (fpath,&st)!=-1){
- if (S_ISDIR(st.st_mode)){
- if (strcmp(pt,".")!=0
- && strcmp(pt,"..")!=0){
- datetime_zonelst (skip_prefix
- ,tbf,fpath);
- }
- }else if(S_ISREG(st.st_mode)
- && strcmp(pt,"time.doc")!=0
- && ! (st.st_mode & 0100)){
- // As you see, we only collect regular
- // file. All others (directories, special
- // files or files that can't be stat will
- // be thrown away.
- replace = fpath+skip_prefix;
- }
- }
- str->setfrom(replace);
- }
- }
-
- static void datetime_zonelst (FIELD_COMBO *comb)
- {
- SSTRINGS tbf;
- datetime_zonelst (strlen(USR_LIB_ZONEINFO)+1
- ,tbf,USR_LIB_ZONEINFO);
- tbf.sort();
- int nb = tbf.getnb();
- for (int i=0; i<nb; i++){
- const char *pt = tbf.getitem(i)->get();
- if (pt[0] != '\0') comb->addopt (pt);
- }
- }
-
- /*
- Get or set the current zoneinfo by reading the symbolic link
- /usr/lib/zoneinfo/localtime.
-
-
- */
- static void datetime_getsetcurzone(SSTRING &str)
- {
- /* #Specification: netconf / datetime / zoneinfo / current
- netconf finds out the current zone by looking at the
- symbolic links /usr/lib/zoneinfo/localtime.
-
- It will follow this link up to five time.
-
- When setting the new time zone, it will also follows
- the links and redo only the last one. The idea here is
- that it support both strategy
-
- #
- ln -sf /usr/lib/zoneinfo/country/value /usr/lib/zoneinfo/localtime
- #
-
- and
-
- #
- ln -sf /usr/lib/zoneinfo/country/value /var/lib/zoneinfo/localtime
- ln -sf /var/lib/zoneinfo/localtime /usr/lib/zoneinfo/localtime
- #
-
- The later being more "correct" fsstnd wise.
- */
- int iter = 0;
- char path[PATH_MAX];
- strcpy (path,USR_LIB_LOCALTIME);
- while (iter < 5){
- char buf[PATH_MAX];
- int nb = readlink (path,buf,sizeof(buf)-1);
- if (nb != -1){
- buf[nb] = '\0';
- struct stat st;
- if (lstat(buf,&st)!=-1 && S_ISLNK(st.st_mode)){
- strcpy (path,buf);
- iter++;
- }else{
- if (str.is_empty()){
- int skip = 0;
- static const char *prefix = USR_LIB_ZONEINFO "/";
- static int len = strlen(prefix);
- if (strncmp(prefix,buf,len) == 0) skip = len;
- str.setfrom (buf+skip);
- }else{
- unlink (path);
- const char *pt = str.get();
- if (pt[0] != '/'){
- sprintf (buf,"%s/%s",USR_LIB_ZONEINFO,pt);
- pt = buf;
- }
- symlink (pt,path);
- }
- break;
- }
- }
- }
- }
- PUBLIC int DATETIME::edit ()
- {
- int ret = -1;
- if (perm_rootaccess(MSG_U(P_CHGDATE,"correct the date and time"))){
- DIALOG dia;
- SSTRING year,month,mday,hour,minutes,seconds;
- {
- time_t t;
- time (&t);
- struct tm *tmt = localtime (&t);
- month.setfrom (tmt->tm_mon+1);
- year.setfrom (tmt->tm_year);
- mday.setfrom (tmt->tm_mday);
- hour.setfrom (tmt->tm_hour);
- minutes.setfrom (tmt->tm_min);
- seconds.setfrom (tmt->tm_sec);
- }
- SSTRING zone;
- datetime_getsetcurzone (zone);
- FIELD_COMBO * comb = dia.newf_combo (MSG_U(F_ZONE,"zone"),zone);
- datetime_zonelst (comb);
- dia.newf_chk (MSG_U(F_STORECMOS,"Store date in CMOS"),universal
- ,MSG_U(F_UNIVERSAL,"universal format(GMT)"));
- dia.newf_str (MSG_U(F_GETDATE,"Get date from server(s)"),netdate);
- dia.newf_title ("",MSG_U(T_TIME,"Time"));
- dia.newf_str (MSG_U(F_HOUR,"Hour"),hour);
- dia.newf_str (MSG_U(F_MINUTES,"Minutes"),minutes);
- dia.newf_str (MSG_U(F_SECONDS,"Seconds"),seconds);
- dia.newf_title ("",MSG_U(T_DATE,"Date"));
- dia.newf_str (MSG_U(F_YEAR,"Year"),year);
- dia.newf_str (MSG_U(F_MONTH,"Month"),month);
- dia.newf_str (MSG_U(F_DAYOFMONTH,"Day of month"),mday);
- if (dia.edit (MSG_U(T_DATETIME,"Workstation date & time")
- ,MSG_U(I_DATETIME
- ,"Fill this form to indicate how the workstation must\n"
- "get its date and time\n")
- ,help_date.getpath(),0) == MENU_ACCEPT){
- datetime_getsetcurzone (zone);
- struct tm tmt;
- tmt.tm_hour = hour.getval();
- tmt.tm_min = minutes.getval();
- tmt.tm_sec = seconds.getval();
- tmt.tm_year = year.getval();
- if (tmt.tm_year > 1900) tmt.tm_year -= 1900;
- tmt.tm_mon = month.getval()-1;
- tmt.tm_mday = mday.getval();
- tmt.tm_isdst = -1;
- save();
- if (netdate.is_empty()){
- time_t t = mktime (&tmt);
- stime (&t);
- }else{
- getfromnet();
- }
- updatecmos();
- ret = 0;
- }
- }
- return ret;
- }
-
- PUBLIC void DATETIME::updatecmos()
- {
- netconf_system_if ("clock",universal ? "-w -u" : "-w");
- }
- /*
- Get the date from CMOS
- */
- PUBLIC int DATETIME::getfromcmos()
- {
- return netconf_system_if ("clock",universal ? "-s -u" : "-s");
- }
-
- /*
- Get the current date and time from servers on the net.
- This will be done only if configured.
-
- Return -1 if any error.
- Return 0 if ok or if it was not configured to do so.
- */
- PUBLIC int DATETIME::getfromnet()
- {
- int ret = 0;
- if (!netdate.is_empty()){
- ret = netconf_system_if ("netdate",netdate.get());
- if (ret == 0) updatecmos();
- }
- return ret;
- }
-
- int datetime_getfromnet()
- {
- DATETIME dt;
- return dt.getfromnet();
- }
- int datetime_getfromcmos()
- {
- DATETIME dt;
- return dt.getfromcmos();
- }
-
- int datetime_edit()
- {
- DATETIME dt;
- return dt.edit();
- }
-
-